using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Deepcode.Flux.Core.Services.XML;
using Deepcode.Flux.Core.Systems.Addins;

namespace Deepcode.Flux.Core.Services.Installation
{
	/// <summary>
	/// Manifest represents a commandset within a setup XML manifest file.
	/// </summary>
	public class Manifest
	{
		private System.Guid		_ApplicationGuid;
		private string			_ApplicationName;
		private System.Version	_ApplicationInstalledVersion;
		private XmlNode			_CommandsetNode = null;

		/// <summary>
		/// Returns the guid of the application as specified in the manifest
		/// </summary>
		public Guid		ApplicationGuid{ get{ return _ApplicationGuid; }}
		/// <summary>
		/// Returns the application name as specified in the manifest (might be empty string)
		/// </summary>
		public string	ApplicationName{ get{ return _ApplicationName; }}
		/// <summary>
		/// Returns the installed version of the application (0.0.0 for not installed)
		/// </summary>
		public Version	ApplicationInstalledVersion{ get{ return _ApplicationInstalledVersion; }}
		/// <summary>
		/// Returns the list of XML command nodes to process for the currently installed version
		/// </summary>
		public XmlNodeList CommandsetNodes
		{
			get
			{
				return _CommandsetNode.ChildNodes;
			}
		}
		/// <summary>
		/// Loads the appropriate commandset from the manifest file
		/// </summary>
		/// <param name="ManifestFile"></param>
		/// <returns></returns>
		public bool LoadCommandset( string ManifestFile )
		{
			XmlUtilityService xmlutil = new XmlUtilityService();

			// Prepare the document and load it
			XmlDocument doc = new XmlDocument();
			doc.Load( ManifestFile );
			
			// Get the root element and extract information
			XmlNode ManifestNode = doc.DocumentElement;
			_ApplicationGuid = xmlutil.GetSafe(ManifestNode, "guid", System.Guid.Empty);
			_ApplicationName = xmlutil.GetSafe(ManifestNode, "name", "");
			
			// Get the addin information in the database
			KnownAddins addins = new KnownAddins();
			KnownAddin addin = addins.GetByGuid( ApplicationGuid );
			if( addin == null )
				_ApplicationInstalledVersion = new Version(0,0,0);
			else
				_ApplicationInstalledVersion = new Version( addin.VersionString );

			// Find the update commandset for the currently installed version stamp
			// This could all just be done with an XPath statement
			foreach( XmlNode node in ManifestNode )
			{
				if( node.NodeType == XmlNodeType.Element )
				{
					if( node.Name == "Update" )
					{
						string fromV = xmlutil.GetSafe(node, "from", "");
						System.Version fromVersion = new Version(fromV);

						if( fromVersion == _ApplicationInstalledVersion )
						{
							_CommandsetNode = node;
							break;
						}
					}
				}
			}
			if( _CommandsetNode == null ) throw new Exception("No update path in " + ManifestFile + " for " + _ApplicationInstalledVersion.ToString());
			return true;
		}

	}
}
